package com.gjt.clientSocket;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;

/**
 * Created with Intel IDEA.
 *
 *  使用socket 写入服务器:只需要向Socket请求一个输出流以及一个输入流（双向tcp不过一般读写不同时进行）
 *   dict协议：字典协议  响应以一个。结束 如果字典中不包含你请求的单词，返回552no match(无匹配)；
 *
 *   半关闭SOCKET: close() 方法关闭输入和输出
 *         public void shutdownInput: 关闭输入流，之后在读取就会返回-1
 *         public void shutdownOutput: 关闭输出流，之后再写就要抛出io异常
 *         并不会关闭Socket；只会影响流
 *
 *         // 判断输入流/输出流是否关闭
 *         public boolean isInputShutdown()
 *         public boolean isOutputShutdown()
 *
 *   Socket的构造函数（不仅创建Socket 对象还尝试连接远程主机）
 *           public Socket(String host, int port)
 *           public Socket(InetAddress host, int port)
 *      notes: 如果域名服务器无法解析这个主机名或者服务器没有运行 ，会抛出UnknownHostException
 *             如果处于原因不能打开Socket 则会抛出IOException
 *
 *    这些构造函数可以创建未连接的Socket
 *          public Socket()
 *          public Socket(Proxy proxy)
 *          public Socket(SocketImpl impl)
 *    指定主机和端口
 *          public Socket(String host, int port, InetAddress interface, int localPort)
 *          public Socket(InetAddress host, int port, InetAddress interface, int localPort)
 *          其中后两个参数是指定的本地网络接口（可以是物理接口，以太网卡，也可以是虚拟接口）和端口连接，如果localPort 是0 则会随机1024- 65535选一个
 *
 *
 *   将用户在命令行上输入的所有单词翻译成汉语
 * @Auther: gjt
 * @Date: 2024/4/8 10:48
 */
public class DictClient {

    private static final String SERVER = "dict.org";
    private static final int port = 2628;
    private static final int TIMEOUT = 15000;


    /**
     * 
     */
    private static void conn(){

        // 类似以前的url 和uri
        try(Socket socket = new Socket("dict.org",2628)){
            // 设置超时时间防止连接服务器时服务器挂起
            socket.setSoTimeout(15000);

            // 获取输出流OutputStream
            OutputStream outputStream = socket.getOutputStream();

            // 连接到字符流中
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));

            // 现在可以用这个命令
            bufferedWriter.write("define english gold\r\n");
            bufferedWriter.flush();


            // 获取输入流
            InputStream inputStream = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
            for(String line = reader.readLine(); !line.equals("."); line = reader.readLine()){
                System.out.println(line);
            }

            bufferedWriter.write("quit\r\n");
            bufferedWriter.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    /**
     *  使用dict 服务器查找单词
     * @param word 单词
     */

    static void transaction(String word){
        try(Socket socket= new Socket(SERVER,port)){
            // 防止服务器挂机
            socket.setSoTimeout(TIMEOUT);

            // 获取输出流
            OutputStream out = socket.getOutputStream();
            BufferedWriter buf = new BufferedWriter(new OutputStreamWriter(out,"UTF-8"));
            buf.write("define english " + word + "\r\n");
            // 一定刷新
            buf.flush();


            InputStream in = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            for(String line = reader.readLine(); line != null; line = reader.readLine()){
                if(line.startsWith("250")){ // ok
                    return;
                }else if (line.startsWith("552")){ // 表示没有匹配到单词
                    System.out.println("Not definition found for" + word);
                    return;
                } else if (line.matches("\\d\\d\\d .*")) {continue;

                } else if (line.trim().equals(".")) {
                    continue;
                } else System.out.println(line);
            }

            // 表示退出
            buf.write("quit\r\n");
            buf.flush();
        }catch (IOException e){
            e.printStackTrace();
        }

    }


    /**
     *  查看本机前1024 端口中那些安装TCP 服务器
     */
    private static void searchTCPPort() {
        String host = "localhost";

        for (int i = 1; i < 1024; i++) {
            try{
                Socket socket = new Socket(host, i);
                System.out.println("There is a server on port " + i + " of" +host);
                // 关闭Socket
                socket.close();
            }catch(UnknownHostException e){
                System.err.println(e);
                break;
            }catch (IOException ex){
                // 这个端口上不是服务器
            }
        }
    }


    /**
     * 构建Socket 但不链接
     */
    private void createSocketDisconnect(){

        // 构建了Socket 但没有连接
        try(Socket socket = new Socket()){
            // 填入socket 选项
            SocketAddress address = new InetSocketAddress("time.nist.gov", 13);

            // 构建连接
            socket.connect(address);
            // 构建超时的连接
            socket.connect(address,15000);

        }catch (UnknownHostException e){
            e.printStackTrace();
        }catch (IOException ex){
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
//        conn();
//        transaction("like");
        searchTCPPort();
    }

}
